#pragma once
#include "test_camera.h"
#include "cm_uart.h"
#include "cm_demo_uart.h"
#include "stdlib.h"
#include "stdint.h"
#include "string.h"
#include "cm_fs.h"
#include "cm_iomux.h"
#include "cm_gpio.h"

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

#define CAPTURE_FILE_NAME   "capture.yuv"


//raw8 640 * 486 spi 2 lan sdr crc  20fps
static const cm_cam_regval_tab GC032a_init_raw8_spi2lan_crc_sdr[] = {
    {0xf3, 0x83},   /*System*/
    {0xf5, 0x0c},
    {0xf7, 0x13},   //    {0xf7, 0x11},
    {0xf8, 0x0f},   //20fps
    {0xf9, 0x4e},
    {0xfa, 0x10},
    {0xfc, 0x02},
    {0xfe, 0x02},
    {0x81, 0x03},
    {0xfe, 0x00},   /*Analog&Cisctl*/
    {0x03, 0x01},
    {0x04, 0xc2},
    {0x05, 0x01},
    {0x06, 0xa3},
    {0x07, 0x00},
    {0x08, 0x08},
    {0x0a, 0x04},
    {0x0c, 0x04},
    {0x0d, 0x01},
    {0x0e, 0xe8},
    {0x0f, 0x02},
    {0x10, 0x88},
    {0x17, 0x54},
    {0x19, 0x04},
    {0x1a, 0x0a},
    {0x1f, 0x40},
    {0x20, 0x30},
    {0x2e, 0x80},
    {0x2f, 0x2b},
    {0x30, 0x1a},
    {0xfe, 0x02},
    {0x03, 0x02},   //[4:0]post_tx_width
    {0x06, 0x60},   //[5:4]stsbp_mode
    {0x05, 0xd7},   //drv
    {0x12, 0x89},   //[7:6]init_ramp_mode
    {0xfe, 0x03},   /*SPI*/
    {0x51, 0x00},   //stream off
    {0x52, 0xda},
    {0x53, 0x24},   //no crc 0x24     crc 0xa4
    {0x54, 0x00},
    {0x55, 0x00},
    {0x59, 0x30},   //    {0x59, 0x30},
    {0x5a, 0x02},   //0x01  type
    {0x5b, 0x80},
    {0x5c, 0x02},
#if 0 /* defined (CONFIG_BOARD_CRANEM_EVB) */
    {0x5d, 0xe0}, // e0
#else
    {0x5d, 0xe6}, // e0
#endif
    {0x5e, 0x01},
    {0x64, 0x06},
    {0xfe, 0x00},   /*blk*/
    {0x18, 0x02},
    {0xfe, 0x02},
    {0x40, 0x22},
    {0x45, 0x00},
    {0x46, 0x00},
    {0x49, 0x20},
    {0x4b, 0x3c},
    {0x50, 0x20},
    {0x42, 0x10},
    {0xfe, 0x01},   /*isp*/
    {0x0a, 0xc5},
    {0x45, 0x00},   //[6]darksun_en
    {0xfe, 0x00},
    {0x40, 0xff},
    {0x41, 0x25},
    {0x42, 0xcf},
    {0x43, 0x10},
    {0x44, 0x99},
    {0x46, 0x26},
    {0x49, 0x03},
    {0x4f, 0x01},   //[0]AEC_en
    {0xde, 0x84},
    {0xfe, 0x02},
    {0x22, 0xf6},   //CISCTL_SUN_TH_R

    {0xfe, 0x00},
    {0x0a, 0x02},
    {0x55, 0x01},
    {0x56, 0xe6},

    {0xfe, 0x01},
    {0x0a, 0x65},
    {0xfe, 0x00},
    {0x4f, 0x00}, //aec off
    {0x42, 0x80}, //awb off
    {0x40, 0x1f}, //cc off
    {0x43, 0x00}, //gamma off

    {0xfe, 0x00},   //Analog&Cisctl
    {0x03, 0x06},    //0x01   exp_high[3:0]   exposure[11:8]
    {0x04, 0xb0},    //0xc2   exp_low[7:0]    exposure[7:0]

};

//yuv422 640 * 480 spi 2 lan sdr
static const cm_cam_regval_tab gc032a_init_yuv422_spi2lan_nocrc_sdr[] = {
    // 15 fps
    {0xf3, 0x83},   /*System*/
    {0xf5, 0x0c},
    {0xf7, 0x13},   //    {0xf7, 0x11},
    {0xf8, 0x0f},
    {0xf9, 0x4e},
    {0xfa, 0x31}, //{0xfa, 0x10},
    {0xfc, 0x02},
    {0xfe, 0x02},
    {0x81, 0x03},
    
    {0xfe, 0x00},   /*Analog&Cisctl*/
    {0x03, 0x01},
    {0x04, 0xc2},
    {0x05, 0x01},
    {0x06, 0xa3},
    {0x07, 0x00},
    {0x08, 0x08},
    {0x0a, 0x04},
    {0x0c, 0x04},
    {0x0d, 0x01},
    {0x0e, 0xe8},
    {0x0f, 0x02},
    {0x10, 0x88},
    {0x17, 0x54},
    {0x19, 0x04},
    {0x1a, 0x0a},
    {0x1f, 0x40},
    {0x20, 0x30},
    {0x2e, 0x80},
    {0x2f, 0x2b},
    {0x30, 0x1a},
    {0xfe, 0x02},
    {0x03, 0x02},   //[4:0]post_tx_width
    {0x06, 0x60},   //[5:4]stsbp_mode
    {0x05, 0xd7},   //drv
    {0x12, 0x89},   //[7:6]init_ramp_mode
    {0xfe, 0x03},   /*SPI*/
    {0x51, 0x00},   //stream off
    {0x52, 0xda},
    {0x53, 0x24},   //no crc 0x24     crc 0xa4
    {0x54, 0x20},
    {0x55, 0x00},
    {0x59, 0x10},   //    {0x59, 0x30},
    {0x5a, 0x00},   //0x01  type
    {0x5b, 0x80},
    {0x5c, 0x02},
    {0x5d, 0xe0}, // e0
    {0x5e, 0x01},
    {0x64, 0x06},
    {0xfe, 0x00},   /*blk*/
    {0x18, 0x02},
    {0xfe, 0x02},
    {0x40, 0x22},
    {0x45, 0x00},
    {0x46, 0x00},
    {0x49, 0x20},
    {0x4b, 0x3c},
    {0x50, 0x20},
    {0x42, 0x10},
    {0xfe, 0x01},   /*isp*/
    {0x0a, 0xc5},
    {0x45, 0x00},   //[6]darksun_en
    {0xfe, 0x00},
    {0x40, 0xff},
    {0x41, 0x25},
    {0x42, 0xcf},
    {0x43, 0x10},
    {0x44, 0x83},
    {0x46, 0x26},
    {0x49, 0x03},
    {0x4f, 0x01},   //[0]AEC_en
    {0xde, 0x84},
    {0xfe, 0x02},
    {0x22, 0xf6},   //CISCTL_SUN_TH_R
    {0xfe, 0x01},   /*Shading*/
    {0xc1, 0x3c},
    {0xc2, 0x50},
    {0xc3, 0x00},
    {0xc4, 0x32},
    {0xc5, 0x24},
    {0xc6, 0x16},
    {0xc7, 0x08},
    {0xc8, 0x08},
    {0xc9, 0x00},
    {0xca, 0x20},
    {0xdc, 0x8a},
    {0xdd, 0xa0},
    {0xde, 0xa6},
    {0xdf, 0x75},
    {0xfe, 0x01},   /*AWB*/
    {0x7c, 0x09},
    {0x65, 0x06},
    {0x7c, 0x08},
    {0x56, 0xf4},
    {0x66, 0x0f},
    {0x67, 0x84},
    {0x6b, 0x80},
    {0x6d, 0x12},
    {0x6e, 0xb0},
    {0x86, 0x00},
    {0x87, 0x00},
    {0x88, 0x00},
    {0x89, 0x00},
    {0x8a, 0x00},
    {0x8b, 0x00},
    {0x8c, 0x00},
    {0x8d, 0x00},
    {0x8e, 0x00},
    {0x8f, 0x00},
    {0x90, 0xef},
    {0x91, 0xe1},
    {0x92, 0x0c},
    {0x93, 0xef},
    {0x94, 0x65},
    {0x95, 0x1f},
    {0x96, 0x0c},
    {0x97, 0x2d},
    {0x98, 0x20},
    {0x99, 0xaa},
    {0x9a, 0x3f},
    {0x9b, 0x2c},
    {0x9c, 0x5f},
    {0x9d, 0x3e},
    {0x9e, 0xaa},
    {0x9f, 0x67},
    {0xa0, 0x60},
    {0xa1, 0x00},
    {0xa2, 0x00},
    {0xa3, 0x0a},
    {0xa4, 0xb6},
    {0xa5, 0xac},
    {0xa6, 0xc1},
    {0xa7, 0xac},
    {0xa8, 0x55},
    {0xa9, 0xc3},
    {0xaa, 0xa4},
    {0xab, 0xba},
    {0xac, 0xa8},
    {0xad, 0x55},
    {0xae, 0xc8},
    {0xaf, 0xb9},
    {0xb0, 0xd4},
    {0xb1, 0xc3},
    {0xb2, 0x55},
    {0xb3, 0xd8},
    {0xb4, 0xce},
    {0xb5, 0x00},
    {0xb6, 0x00},
    {0xb7, 0x05},
    {0xb8, 0xd6},
    {0xb9, 0x8c},
    {0xfe, 0x01},   /*CC*/
    {0xd0, 0x40},   //3a
    {0xd1, 0xf8},
    {0xd2, 0x00},
    {0xd3, 0xfa},
    {0xd4, 0x45},
    {0xd5, 0x02},
    {0xd6, 0x30},
    {0xd7, 0xfa},
    {0xd8, 0x08},
    {0xd9, 0x08},
    {0xda, 0x58},
    {0xdb, 0x02},
    {0xfe, 0x00},
    {0xfe, 0x00},   /*Gamma*/
    {0xba, 0x00},
    {0xbb, 0x04},
    {0xbc, 0x0a},
    {0xbd, 0x0e},
    {0xbe, 0x22},
    {0xbf, 0x30},
    {0xc0, 0x3d},
    {0xc1, 0x4a},
    {0xc2, 0x5d},
    {0xc3, 0x6b},
    {0xc4, 0x7a},
    {0xc5, 0x85},
    {0xc6, 0x90},
    {0xc7, 0xa5},
    {0xc8, 0xb5},
    {0xc9, 0xc2},
    {0xca, 0xcc},
    {0xcb, 0xd5},
    {0xcc, 0xde},
    {0xcd, 0xea},
    {0xce, 0xf5},
    {0xcf, 0xff},
    {0xfe, 0x00},   /*Auto Gamma*/
    {0x5a, 0x08},
    {0x5b, 0x0f},
    {0x5c, 0x15},
    {0x5d, 0x1c},
    {0x5e, 0x28},
    {0x5f, 0x36},
    {0x60, 0x45},
    {0x61, 0x51},
    {0x62, 0x6a},
    {0x63, 0x7d},
    {0x64, 0x8d},
    {0x65, 0x98},
    {0x66, 0xa2},
    {0x67, 0xb5},
    {0x68, 0xc3},
    {0x69, 0xcd},
    {0x6a, 0xd4},
    {0x6b, 0xdc},
    {0x6c, 0xe3},
    {0x6d, 0xf0},
    {0x6e, 0xf9},
    {0x6f, 0xff},
    {0xfe, 0x00},   /*Gain*/
    {0x70, 0x50},
    {0xfe, 0x00},   /*AEC*/
    {0x4f, 0x01},
    {0xfe, 0x01},
    {0x44, 0x04},
    {0x1f, 0x30},
    {0x20, 0x40},
    {0x26, 0x4e},
    {0x27, 0x01},
    {0x28, 0xd4},
    {0x29, 0x03},
    {0x2a, 0x0c},
    {0x2b, 0x03},
    {0x2c, 0xe9},
    {0x2d, 0x07},
    {0x2e, 0xd2},
    {0x2f, 0x0b},
    {0x30, 0x6e},
    {0x31, 0x0e},
    {0x32, 0x70},
    {0x33, 0x12},
    {0x34, 0x0c},
    {0x3c, 0x10},   //[5:4] Max level setting
    {0x3e, 0x20},
    {0x3f, 0x2d},
    {0x40, 0x40},
    {0x41, 0x5b},
    {0x42, 0x82},
    {0x43, 0xb7},
    {0x04, 0x0a},
    {0x02, 0x79},
    {0x03, 0xc0},
    {0xcc, 0x08},   /*measure window*/
    {0xcd, 0x08},
    {0xce, 0xa4},
    {0xcf, 0xec},
    {0xfe, 0x00},   /*DNDD*/
    {0x81, 0xb8},   //f8
    {0x82, 0x12},
    {0x83, 0x0a},
    {0x84, 0x01},
    {0x86, 0x50},
    {0x87, 0x18},
    {0x88, 0x10},
    {0x89, 0x70},
    {0x8a, 0x20},
    {0x8b, 0x10},
    {0x8c, 0x08},
    {0x8d, 0x0a},
    {0xfe, 0x00},   /*Intpee*/
    {0x8f, 0xaa},
    {0x90, 0x9c},
    {0x91, 0x52},
    {0x92, 0x03},
    {0x93, 0x03},
    {0x94, 0x08},
    {0x95, 0x44},
    {0x97, 0x00},
    {0x98, 0x00},
    {0xfe, 0x00},   /*ASDE*/
    {0xa1, 0x30},
    {0xa2, 0x41},
    {0xa4, 0x30},
    {0xa5, 0x20},
    {0xaa, 0x30},
    {0xac, 0x32},
    {0xfe, 0x00},   /*YCP*/
    {0xd1, 0x3c},
    {0xd2, 0x3c},
    {0xd3, 0x38},
    {0xd6, 0xf4},
    {0xd7, 0x1d},
    {0xdd, 0x73},
    {0xde, 0x84},
     //{0x4c, 0x08}   //for color bar
};

//yuv422 640 * 480 spi 2 lan ddr
static const cm_cam_regval_tab gc032a_init_yuv422_640x480_spi2lan_nocrc_ddr[] = {
    /*System*/
    {0xf3, 0xe3},
    {0xf5, 0x0c},
    {0xf7, 0x01},
    {0xf8, 0x03},
    {0xf9, 0x4e},
    {0xfa, 0x00},
    {0xfc, 0x02},
    {0xfe, 0x02},
    {0x81, 0x03},

    /*Analog&Cisctl*/
    {0xfe, 0x00},
    {0x03, 0x01}, // exp
    {0x04, 0xce},
    {0x05, 0x01},
    {0x06, 0xad},
    {0x07, 0x00},
    {0x08, 0x10},
    {0x0a, 0x04},
    {0x0c, 0x04},
    {0x0d, 0x01},
    {0x0e, 0xe8},
    {0x0f, 0x02},
    {0x10, 0x88},
    {0x17, 0x54},
    {0x19, 0x04},
    {0x1a, 0x0a},
    {0x1f, 0x40},
    {0x20, 0x30},
    {0x2e, 0x80},
    {0x2f, 0x2b},
    {0x30, 0x1a},
    {0xfe, 0x02},
    {0x03, 0x02},
    {0x05, 0xd7},
    {0x06, 0x60},
    {0x08, 0x80},
    {0x12, 0x89},

    /*SPI*/
    {0xfe, 0x03},
    {0x51, 0x01},
    {0x52, 0xfa},
    {0x53, 0x24},
    {0x54, 0x20},
    {0x55, 0x00},
    {0x59, 0x10},
    {0x5a, 0x00},
    {0x5b, 0x80},
    {0x5c, 0x02},
    {0x5d, 0xe0},
    {0x5e, 0x01},

    /*blk*/
    {0xfe, 0x00},
    {0x18, 0x02},
    {0xfe, 0x02},
    {0x40, 0x22},
    {0x45, 0x00},
    {0x46, 0x00},
    {0x49, 0x20},
    {0x4b, 0x3c},
    {0x50, 0x20},
    {0x42, 0x10},

    /*isp*/
    {0xfe, 0x01},
    {0x0a, 0xc5},
    {0x45, 0x00},
    {0xfe, 0x00},
    {0x40, 0xff},
    {0x41, 0x25},
    {0x42, 0xcf},
    {0x43, 0x10},
    {0x44, 0x83},
    {0x46, 0x26},
    {0x49, 0x03},
    {0xfe, 0x02},
    {0x22, 0xf6},

    /*Shading*/
    {0xfe, 0x01},
    {0xc1, 0x3c},
    {0xc2, 0x50},
    {0xc3, 0x00},
    {0xc4, 0x32},
    {0xc5, 0x24},
    {0xc6, 0x16},
    {0xc7, 0x08},
    {0xc8, 0x08},
    {0xc9, 0x00},
    {0xca, 0x20},
    {0xdc, 0x8a},
    {0xdd, 0xa0},
    {0xde, 0xa6},
    {0xdf, 0x75},

    /*AWB*/
    {0xfe, 0x01},
    {0x7c, 0x09},
    {0x65, 0x06},
    {0x7c, 0x08},
    {0x56, 0xf4},
    {0x66, 0x0f},
    {0x67, 0x84},
    {0x6b, 0x80},
    {0x6d, 0x12},
    {0x6e, 0xb0},
    {0x86, 0x00},
    {0x87, 0x00},
    {0x88, 0x00},
    {0x89, 0x00},
    {0x8a, 0x00},
    {0x8b, 0x00},
    {0x8c, 0x00},
    {0x8d, 0x00},
    {0x8e, 0x00},
    {0x8f, 0x00},
    {0x90, 0xef},
    {0x91, 0xe1},
    {0x92, 0x0c},
    {0x93, 0xef},
    {0x94, 0x65},
    {0x95, 0x1f},
    {0x96, 0x0c},
    {0x97, 0x2d},
    {0x98, 0x20},
    {0x99, 0xaa},
    {0x9a, 0x3f},
    {0x9b, 0x2c},
    {0x9c, 0x5f},
    {0x9d, 0x3e},
    {0x9e, 0xaa},
    {0x9f, 0x67},
    {0xa0, 0x60},
    {0xa1, 0x00},
    {0xa2, 0x00},
    {0xa3, 0x0a},
    {0xa4, 0xb6},
    {0xa5, 0xac},
    {0xa6, 0xc1},
    {0xa7, 0xac},
    {0xa8, 0x55},
    {0xa9, 0xc3},
    {0xaa, 0xa4},
    {0xab, 0xba},
    {0xac, 0xa8},
    {0xad, 0x55},
    {0xae, 0xc8},
    {0xaf, 0xb9},
    {0xb0, 0xd4},
    {0xb1, 0xc3},
    {0xb2, 0x55},
    {0xb3, 0xd8},
    {0xb4, 0xce},
    {0xb5, 0x00},
    {0xb6, 0x00},
    {0xb7, 0x05},
    {0xb8, 0xd6},
    {0xb9, 0x8c},

    /*CC*/
    {0xfe, 0x01},
    {0xd0, 0x40},//3a
    {0xd1, 0xf8},
    {0xd2, 0x00},
    {0xd3, 0xfa},
    {0xd4, 0x45},
    {0xd5, 0x02},

    {0xd6, 0x30},
    {0xd7, 0xfa},
    {0xd8, 0x08},
    {0xd9, 0x08},
    {0xda, 0x58},
    {0xdb, 0x02},
    {0xfe, 0x00},

    /*Gamma*/
    {0xfe, 0x00},
    {0xba, 0x00},
    {0xbb, 0x04},
    {0xbc, 0x0a},
    {0xbd, 0x0e},
    {0xbe, 0x22},
    {0xbf, 0x30},
    {0xc0, 0x3d},
    {0xc1, 0x4a},
    {0xc2, 0x5d},
    {0xc3, 0x6b},
    {0xc4, 0x7a},
    {0xc5, 0x85},
    {0xc6, 0x90},
    {0xc7, 0xa5},
    {0xc8, 0xb5},
    {0xc9, 0xc2},
    {0xca, 0xcc},
    {0xcb, 0xd5},
    {0xcc, 0xde},
    {0xcd, 0xea},
    {0xce, 0xf5},
    {0xcf, 0xff},

    /*Auto Gamma*/
    {0xfe, 0x00},
    {0x5a, 0x08},
    {0x5b, 0x0f},
    {0x5c, 0x15},
    {0x5d, 0x1c},
    {0x5e, 0x28},
    {0x5f, 0x36},
    {0x60, 0x45},
    {0x61, 0x51},
    {0x62, 0x6a},
    {0x63, 0x7d},
    {0x64, 0x8d},
    {0x65, 0x98},
    {0x66, 0xa2},
    {0x67, 0xb5},
    {0x68, 0xc3},
    {0x69, 0xcd},
    {0x6a, 0xd4},
    {0x6b, 0xdc},
    {0x6c, 0xe3},
    {0x6d, 0xf0},
    {0x6e, 0xf9},
    {0x6f, 0xff},

    /*Gain*/
    {0xfe, 0x00},
    {0x70, 0x50},

    /*AEC*/
    {0xfe, 0x00},
    {0x4f, 0x01}, // aec_en
    {0xfe, 0x01},
    {0x12, 0xa0},
    {0x13, 0x3a},
    {0x44, 0x04},
    {0x1f, 0x30},
    {0x20, 0x40},
    {0x26, 0x9a},
    {0x27, 0x01},
    {0x28, 0xce},
    {0x29, 0x02},
    {0x2a, 0x68},
    {0x2b, 0x03},
    {0x2c, 0x9c},
    {0x2d, 0x07},
    {0x2e, 0xd2},
    {0x2f, 0x0b},
    {0x30, 0x6e},
    {0x31, 0x0e},
    {0x32, 0x70},
    {0x33, 0x12},
    {0x34, 0x0c},
    {0x3c, 0x20}, //[5:4] Max level setting
    {0x3e, 0x20},
    {0x3f, 0x2d},
    {0x40, 0x40},
    {0x41, 0x5b},
    {0x42, 0x82},
    {0x43, 0xb7},
    {0x04, 0x0a},
    {0x02, 0x79},
    {0x03, 0xc0},

    /*measure window*/
    {0xcc, 0x08},
    {0xcd, 0x08},
    {0xce, 0xa4},
    {0xcf, 0xec},

    /*DNDD*/
    {0xfe, 0x00},
    {0x81, 0xb8},//f8
    {0x82, 0x12},
    {0x83, 0x0a},
    {0x84, 0x01},
    {0x86, 0x50},
    {0x87, 0x18},
    {0x88, 0x10},
    {0x89, 0x70},
    {0x8a, 0x20},
    {0x8b, 0x10},
    {0x8c, 0x08},
    {0x8d, 0x0a},

    /*Intpee*/
    {0xfe, 0x00},
    {0x8f, 0xaa},
    {0x90, 0x9c},
    {0x91, 0x52},
    {0x92, 0x03},
    {0x93, 0x03},
    {0x94, 0x08},
    {0x95, 0x44},
    {0x97, 0x00},
    {0x98, 0x00},

    /*ASDE*/
    {0xfe, 0x00},
    {0xa1, 0x30},
    {0xa2, 0x41},
    {0xa4, 0x30},
    {0xa5, 0x20},
    {0xaa, 0x30},
    {0xac, 0x32},

    /*YCP*/
    {0xfe, 0x00},
    {0xd1, 0x3c},
    {0xd2, 0x3c},
    {0xd3, 0x38},
    {0xd6, 0xf4},
    {0xd7, 0x1d},
    {0xdd, 0x73},
    {0xde, 0x84},

     //{0x4c, 0x08}   //for color bar
};


static const cm_cam_regval_tab GC032a_id[] = {
    {0xf0, 0x23},
    {0xf1, 0x2a},
};
static const cm_cam_regval_tab GC032a_vts[] = {
    {0x00, 0x00},
};

static const cm_cam_regval_tab GC032a_stream_on[] = {
    {0xfe, 0x03},
    {0x51, 0x01},
};
static const cm_cam_regval_tab GC032a_stream_off[] = {
    {0xfe, 0x03},
    {0x51, 0x00},
};
static const cm_cam_regval_tab GC032a_expo[] = {
    {0xfe, 0x00},    //page select
    {0x03, 0x01},    //exp_high
    {0x04, 0x00},    //exp_low
};
static const cm_cam_regval_tab GC032a_gain[] = {
    {0xfe, 0x00},    //page select
    {0x48, 0x01},    //gain
};


static const cm_cam_regval_tab GC032a_vflip[] = {
    {0x00, 0x00},
};
static const cm_cam_regval_tab GC032a_hflip[] = {
    {0x00, 0x00},
};

static cm_cam_sensor_i2c_attr GC032a_i2c_attr[] = {
    {
        CAM_I2C_8BIT,
        CAM_I2C_8BIT,
        0x21,//0x42,
    }
};

static cm_cam_sensor_module GC032a_MODULE_INFO[] = {
    {
        0x01,
        "0x01",
        0,
    },
    {
        0xff,
        "0xff",
        0,
    },
};

static cm_cam_sensor_resolution GC032a_resolution[] = {
    {
        CAM_SENSOR_FMT_RAW8,
        MEDIA_BUS_FMT_SRGGB8_1X8,
        640,
        486,
        0x0708,
        0x0d06,
        30,
        15,
        CAM_SENSOR_RES_BINING1,
        {
            GC032a_init_raw8_spi2lan_crc_sdr,
            ARRAY_SIZE(GC032a_init_raw8_spi2lan_crc_sdr),
        },
    },
    {
        CAM_SENSOR_FMT_YUV422,
        MEDIA_BUS_FMT_YVYU8_2X8,
        640,
        480,
        0x0708,
        0x0d06,
        30,
        15,
        CAM_SENSOR_RES_BINING1,
        {
            gc032a_init_yuv422_spi2lan_nocrc_sdr,
            ARRAY_SIZE(gc032a_init_yuv422_spi2lan_nocrc_sdr),
        },
    },
    {
        CAM_SENSOR_FMT_YUV422,
        MEDIA_BUS_FMT_YVYU8_2X8,
        640,
        480,
        0x0708,
        0x0d06,
        30,
        15,
        CAM_SENSOR_RES_BINING1,
        {
            gc032a_init_yuv422_640x480_spi2lan_nocrc_ddr,
            ARRAY_SIZE(gc032a_init_yuv422_640x480_spi2lan_nocrc_ddr),
        },
    },
};

int32_t test_GC032a_ata_open(cm_cam_sensor_ata_t *ata)
{
    return 0;
}

int32_t test_GC032a_update_aec(cm_cam_sensor_aec_t *aec)
{
    int ret = 0;
//    uint32_t val1,val2,val3 = 0;
    uint32_t step_low = 0, step_high = 0;
    uint32_t step = 0;
    uint32_t min_exp = 0, max_exp = 0;
    uint32_t min_exp_l = 0, min_exp_h = 0;
    uint32_t max_exp_l = 0, max_exp_h = 0;
    uint32_t min_fps = 0, max_fps = 0;

    cm_cam_sensor_i2c_attr *i2c_attr = GC032a_i2c_attr;

    if (NULL == aec) {
        cm_demo_printf("aec is NULL, return error!\n");
        return 0;
    }
    min_fps = aec->min_fps;
    max_fps = aec->max_fps;
    ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0xfe,0x01);
    ret = cm_camera_sensor_i2c_read(i2c_attr,0x25,&step_high);   // exp line(10ms)
    ret = cm_camera_sensor_i2c_read(i2c_attr,0x26,&step_low);
    ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0xfe,0x00);
    if(aec->sensor_out_yuv){
        cm_demo_printf("GC032a set_fps [%d-%d] banding=%d \n",aec->min_fps, aec->max_fps, aec->banding);
        if(min_fps > max_fps){
            cm_demo_printf("set_fps param error,min_fps must small or equal than max_fps \n");
            return 0;
        }
        if(0 == min_fps)
            min_fps =1;
        if(0 == max_fps)
            max_fps =1;

        step = ((step_high & 0x1f) << 0x8) | step_low;

        min_exp = 100 / (float)max_fps * step;
        max_exp = 100 / (float)min_fps * step;
        cm_demo_printf("set_fps step =0x%x min_exp = 0x%x max_exp = 0x%x\n",step, min_exp,max_exp);

        min_exp_l = min_exp & 0xff;
        min_exp_h = (min_exp >> 0x8) & 0xff;

        max_exp_l = max_exp & 0xff;
        max_exp_h = (max_exp >> 0x8) & 0xff;

        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0xfe,0x01);
        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x27,max_exp_h);//exp  level 1
        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x28,max_exp_l);
        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x29,max_exp_h);//exp  level 2
        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x2a,max_exp_l + 0x1);
        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x2b,max_exp_h);//exp  level 3
        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x2c,max_exp_l + 0x2);
        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x2d,max_exp_h);//exp  level 4
        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x2e,max_exp_l + 0x3);
        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x2f,max_exp_h);//exp  level 5
        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x30,max_exp_l + 0x4);
        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x31,max_exp_h);//exp  level 6
        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x32,max_exp_l + 0x5);
        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x33,max_exp_h);//exp  level 7
        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x34,max_exp_l + 0x6);

        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x3c, 0x0); // max_exp_level[5:4] set 0, MaxLevel=1
        if( 30 > max_fps ){
            ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x3c,min_exp_h); // max_exp_level[5:4] set 0, MaxLevel=1
            ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0x3d,min_exp_l); //min_exp [11:0]
        }
        ret = cm_camera_sensor_i2c_write_single(i2c_attr, 0xfe,0x00);
    } else {
    }
    OCTEST_EXPECT_EQUAL_INT32(0,ret);
    return ret;
}

int32_t test_GC032a_s_power(int32_t on)
{
#ifdef CM_OPENCPU_MODEL_ML305A
    cm_demo_printf("GC032a_s_power %d\n", on);
    cm_gpio_cfg_t cfg = {0, CM_GPIO_DIRECTION_OUTPUT, CM_GPIO_PULL_UP};
    cm_iomux_set_pin_func(CM_IOMUX_PIN_16, CM_IOMUX_FUNC_FUNCTION2); // pwdn1
    cm_gpio_init(CM_GPIO_NUM_18, &cfg);
    cm_gpio_set_level(CM_GPIO_NUM_18, CM_GPIO_LEVEL_LOW);
    cm_iomux_set_pin_func(CM_IOMUX_PIN_48, CM_IOMUX_FUNC_FUNCTION3); // cam_en
    cm_gpio_init(CM_GPIO_NUM_31, &cfg);
    cm_gpio_set_level(CM_GPIO_NUM_31, CM_GPIO_LEVEL_LOW);

    if (on > 0) {
        cm_camera_sensor_set_mclk(0);
        osDelay(1); //delay 5ms
        cm_gpio_set_level(CM_GPIO_NUM_31, CM_GPIO_LEVEL_HIGH);
        osDelay(1);
        cm_camera_sensor_set_mclk(1);
        osDelay(1);
        cm_gpio_set_level(CM_GPIO_NUM_18, CM_GPIO_LEVEL_HIGH);
        osDelay(2);
        cm_gpio_set_level(CM_GPIO_NUM_18, CM_GPIO_LEVEL_LOW);
    } else {
        cm_gpio_set_level(CM_GPIO_NUM_18, CM_GPIO_LEVEL_HIGH);
        osDelay(1); //delay 5ms
        cm_camera_sensor_set_mclk(0);
        osDelay(1);
        cm_gpio_set_level(CM_GPIO_NUM_31, CM_GPIO_LEVEL_LOW);
        osDelay(1);
        cm_gpio_set_level(CM_GPIO_NUM_18, CM_GPIO_LEVEL_LOW);
    }
#endif
#ifdef CM_OPENCPU_MODEL_ML307A
    cm_demo_printf("GC032a_s_power %d\n", on);
    cm_gpio_cfg_t cfg = {0, CM_GPIO_DIRECTION_OUTPUT, CM_GPIO_PULL_UP};
    cm_iomux_set_pin_func(CM_IOMUX_PIN_81, CM_IOMUX_FUNC_FUNCTION2); // pwdn1
    cm_gpio_init(CM_GPIO_NUM_16, &cfg);
    cm_gpio_set_level(CM_GPIO_NUM_16, CM_GPIO_LEVEL_LOW);
    // cm_iomux_set_pin_func(CM_IOMUX_PIN_48, CM_IOMUX_FUNC_FUNCTION3); // cam_en
    // cm_gpio_init(CM_GPIO_NUM_31, &cfg);
    // cm_gpio_set_level(CM_GPIO_NUM_31, CM_GPIO_LEVEL_LOW);

    if (on > 0) {
        cm_camera_sensor_set_mclk(0);
        // osDelay(1); //delay 5ms
        // cm_gpio_set_level(CM_GPIO_NUM_31, CM_GPIO_LEVEL_HIGH);
        osDelay(1);
        cm_camera_sensor_set_mclk(1);
        osDelay(1);
        cm_gpio_set_level(CM_GPIO_NUM_16, CM_GPIO_LEVEL_HIGH);
        osDelay(2);
        cm_gpio_set_level(CM_GPIO_NUM_16, CM_GPIO_LEVEL_LOW);
    } else {
        cm_gpio_set_level(CM_GPIO_NUM_16, CM_GPIO_LEVEL_HIGH);
        osDelay(1); //delay 5ms
        cm_camera_sensor_set_mclk(0);
        // osDelay(1);
        // cm_gpio_set_level(CM_GPIO_NUM_31, CM_GPIO_LEVEL_LOW);
        osDelay(1);
        cm_gpio_set_level(CM_GPIO_NUM_16, CM_GPIO_LEVEL_LOW);
    }
#endif
    return 0;
}

cm_cam_sensor_spec_ops test_GC032a_ops = {
    NULL,
    NULL,
    NULL,
    test_GC032a_s_power,
    test_GC032a_ata_open,
    test_GC032a_update_aec,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
};

static cm_isp_tuning_tab gc032a_tuning_tab[] = {
    //LSC
    {0x680,0x00},    //0C
    {0x684,0x78},    //F0center_row
    {0x688,0xA0},    //A0center_col

    {0x0690,0x77},    //sign of b1
    {0x0694,0x77},    //sign of b1
    {0x0698,0x77},    //sign of b4
    {0x069C,0x70},    //sign of b4
    {0x06A0,0x77},    //sign of b22
    {0x06A4,0x70},    //sign of b22
    {0x06A8,0x03},    //Q1_b1 of R
    {0x06AC,0x1c},    //Q1_b1 of G
    {0x06B0,0x1f},    //Q1_b1 of B
    {0x06B4,0x1c},    //Q2_b1 of R
    {0x06B8,0x44},    //Q2_b1 of G
    {0x06BC,0x2b},    //Q2_b1 of B
    {0x06C0,0x57},    //Q3_b1 of R
    {0x06C4,0x6f},    //Q3_b1 of G
    {0x06C8,0x6a},    //Q3_b1 of B
    {0x06CC,0x14},    //Q4_b1 of R
    {0x06D0,0x24},    //Q4_b1 of G
    {0x06D4,0x2e},    //Q4_b1 of B
    {0x06D8,0xee},    //right_b2 of R
    {0x06DC,0xb6},    //right_b2 of G
    {0x06E0,0x86},    //right_b2 of B
    {0x06E4,0x7f},    //right_b4 of R
    {0x06E8,0x7f},    //right_b4 of G
    {0x06EC,0x7f},    //right_b4 of B
    {0x06F0,0xb2},    //left_b2 of R
    {0x06F4,0x62},    //left_b2 of G
    {0x06F8,0x5e},    //left_b2 of B
    {0x06FC,0x7f},    //left_b4 of R
    {0x0700,0x7f},    //left_b4 of G
    {0x0704,0x7f},    //left_b4 of B
    {0x0708,0xd3},    //up_b2 of R
    {0x070C,0xb0},    //up_b2 of G
    {0x0710,0xa8},    //up_b2 of B
    {0x0714,0x7f},    //up_b4 of R
    {0x0718,0x7f},    //up_b4 of G
    {0x071C,0x7f},    //up_b4 of B
    {0x0720,0x2a},    //down_b2 of R
    {0x0724,0x14},    //down_b2 of G
    {0x0728,0x00},    //down_b2 of B
    {0x072C,0x80},    //down_b4 of R
    {0x0730,0x80},    //down_b4 of G
    {0x0734,0x80},    //down_b4 of B
    {0x0740,0xfe},    //right_up_b22 of R
    {0x0744,0xfe},    //right_up_b22 of G
    {0x0748,0xfe},    //right_up_b22 of B
    {0x074C,0xfe},    //right_down_b22 of R
    {0x0750,0xfe},    //right_down_b22 of G
    {0x0754,0x00},    //right_down_b22 of B
    {0x0758,0xfe},    //left_up_b22 of R
    {0x075C,0xfe},    //left_up_b22 of G
    {0x0760,0xfe},    //left_up_b22 of B
    {0x0764,0xff},    //left_down_b22 of R
    {0x0768,0xff},    //left_down_b22 of G
    {0x076C,0xff},    //left_down_b22 of B
    {0x077C,0x05},

    //AWB
    {0x053C,0x00},
    {0x053C,0x00},
    {0x052C,0x01},
    {0x053C,0x00},

    {0x0530,0x01},//D65
    {0x0534,0x8f},
    {0x0538,0x02},
    {0x0530,0x01},
    {0x0534,0x90},
    {0x0538,0x02},
    {0x0530,0x01},
    {0x0534,0xae},
    {0x0538,0x02},
    {0x0530,0x01},
    {0x0534,0xaf},
    {0x0538,0x02},
    {0x0530,0x01},
    {0x0534,0xb0},
    {0x0538,0x02},

    {0x0530,0x01},//D50
    {0x0534,0x8c},
    {0x0538,0x03},
    {0x0530,0x01},
    {0x0534,0x8d},
    {0x0538,0x03},
    {0x0530,0x01},
    {0x0534,0xac},
    {0x0538,0x03},
    {0x0530,0x01},
    {0x0534,0xad},
    {0x0538,0x03},
    {0x0530,0x01},
    {0x0534,0xae},
    {0x0538,0x03},

    {0x0530,0x01},//CWF
    {0x0534,0xab},
    {0x0538,0x04},
    {0x0530,0x01},
    {0x0534,0xca},
    {0x0538,0x04},
    {0x0530,0x01},
    {0x0534,0xcb},
    {0x0538,0x04},

    {0x0530,0x01},//TL84
    {0x0534,0xeb},
    {0x0538,0x05},
    {0x0530,0x02},
    {0x0534,0x0a},
    {0x0538,0x05},

    {0x0530,0x02},//A
    {0x0534,0x6a},
    {0x0538,0x06},
    {0x0530,0x02},
    {0x0534,0x6b},
    {0x0538,0x06},
    {0x0530,0x02},
    {0x0534,0x8a},
    {0x0538,0x06},
    {0x0530,0x02},
    {0x0534,0x8B},
    {0x0538,0x06},
    {0x0530,0x02},
    {0x0534,0xaa},
    {0x0538,0x06},

    {0x053C,0x01},
    {0x0548,0x05},
    {0x0550,0x1C},
    {0x0574,0x13},
    {0x05d8,0x56},
    {0x05dc,0xa0},
    {0x05e0,0xa0},

    //CC
    {0x0B04,0x59},//D
    {0x0B08,0xF9},
    {0x0B0C,0x05},
    {0x0B10,0xF3},
    {0x0B14,0x5D},
    {0x0B18,0xF2},

    {0x0B1C,0x68},//C
    {0x0B20,0xF3},
    {0x0B24,0x00},
    {0x0B28,0xEC},
    {0x0B2C,0x5F},
    {0x0B30,0xEA},

    {0x0B34,0x5D},//A
    {0x0B38,0xF7},
    {0x0B3C,0xF5},
    {0x0B8c,0x08},
    {0x0B90,0x64},
    {0x0B94,0xCD},

    //YCP
    {0x0B44,0x2e},
    {0x0B48,0x2e},

    //AE_Target
    {0x044C,0x50},

    //block enable
    {0x0200,0x79},

    //////////////frame rate   50Hz
    {0x0494 ,0x00},
    {0x0498 ,0x9c}, //step
    {0x049C ,0x01}, //30fps  level 1
    {0x04A0 ,0xd4},
    {0x04A4 ,0x02},//25fps level 2
    {0x04A8 ,0x70},
    {0x04AC ,0x03}, //20fps level 3
    {0x04B0 ,0x0c},
    {0x04B4 ,0x03}, //16.7fps level 4
    {0x04B8 ,0xa8},
    {0x04BC ,0x06}, // 10fps level 5
    {0x04C0 ,0x18},
    {0x04C4 ,0x08}, // 7.14fps level 6
    {0x04C8 ,0x88},
    {0x04CC ,0x0c}, // 5fps level 7
    {0x04D0 ,0x30},

    //{0x04f0 ,0x60}, // max_exp_level[6:5]
    {0x04f4 ,0x04}, //min_exp [12:0]

};

static cm_isp_tuning_tab gc032a_50hz_banding_tab[] = {
    //////////////frame rate   50Hz
    {0x0494 ,0x00},
    {0x0498 ,0x9b}, //step
    {0x049C ,0x01}, //30fps  level 1
    {0x04A0 ,0xd4},
    {0x04A4 ,0x02},//25fps level 2
    {0x04A8 ,0x70},
    {0x04AC ,0x03}, //20fps level 3
    {0x04B0 ,0x0c},
    {0x04B4 ,0x03}, //16.7fps level 4
    {0x04B8 ,0xa8},
    {0x04BC ,0x06}, // 10fps level 5
    {0x04C0 ,0x18},
    {0x04C4 ,0x08}, // 7.14fps level 6
    {0x04C8 ,0x88},
    {0x04CC ,0x0c}, // 5fps level 7
    {0x04D0 ,0x30},

    //{0x04f0 ,0x60}, // max_exp_level[6:5]
    {0x04f4 ,0x04}, //min_exp [12:0]
};

static cm_isp_tuning_tab gc032a_60hz_banding_tab[] = {
    //////////////frame rate   50Hz
    {0x0494 ,0x00},
    {0x0498 ,0x82}, //step
    {0x049C ,0x01}, //30fps  level 1
    {0x04A0 ,0x86},
    {0x04A4 ,0x02},//25fps level 2
    {0x04A8 ,0x8a},
    {0x04AC ,0x03}, //20fps level 3
    {0x04B0 ,0x0c},
    {0x04B4 ,0x03}, //16.7fps level 4
    {0x04B8 ,0x8e},
    {0x04BC ,0x05}, // 10fps level 5
    {0x04C0 ,0x96},
    {0x04C4 ,0x08}, // 7.14fps level 6
    {0x04C8 ,0x20},
    {0x04CC ,0x0c}, // 5fps level 7
    {0x04D0 ,0x30},

    //{0x04f0 ,0x60}, // max_exp_level[6:5]
    {0x04f4 ,0x04}, //min_exp [12:0]
};

cm_cam_sensor_data_t test_GC032a_spi = {
    "gc032a_spi",
    &test_GC032a_ops,
    0,
    GC032a_i2c_attr,
    ARRAY_SIZE(GC032a_i2c_attr),
    {
        GC032a_id,
        ARRAY_SIZE(GC032a_id),
    },
    NULL,
    0,
    GC032a_resolution,
    ARRAY_SIZE(GC032a_resolution),
    {
        GC032a_stream_on,
        ARRAY_SIZE(GC032a_stream_on),
    },
    {
        GC032a_stream_off,
        ARRAY_SIZE(GC032a_stream_off),
    },
    {
        GC032a_expo,
        ARRAY_SIZE(GC032a_expo),
    },
    {
        GC032a_vts,
        ARRAY_SIZE(GC032a_vts),
    },
    {
        GC032a_gain,
        ARRAY_SIZE(GC032a_gain),
    },
    {
        GC032a_hflip,
        ARRAY_SIZE(GC032a_hflip),
    },
    {
        GC032a_vflip,
        ARRAY_SIZE(GC032a_vflip),
    },
    GC032a_MODULE_INFO,
    ARRAY_SIZE(GC032a_MODULE_INFO),
    gc032a_tuning_tab,
    ARRAY_SIZE(gc032a_tuning_tab),
    {
        {
            gc032a_50hz_banding_tab,
            ARRAY_SIZE(gc032a_50hz_banding_tab),
        },
        {
            gc032a_60hz_banding_tab,
            ARRAY_SIZE(gc032a_60hz_banding_tab),
        },
    },
    0,  //CAM_SPI: spi    CAM_MIPI: mipi
    1,// .lane_num
    0,  //0x0:sdr   0x1:ddr spi_sdr
    0,  //0x0:no crc   0x1:crc,.spi_crc
    100,//.reset_delay
    0,  //auto set .cur_i2c_index
    1, //YUV format used
    //0, //RAW8 format used
};
static void cm_test_enqueueCamRecordBuffer_callback(void *pBuf, uint32_t len)
{
    cm_demo_printf("enqueueCamRecordBuffer %d\n", len);
    static int state = 0;
    static char preview_name[] = "PREVIEW_FILE_1.yuv";
    if(state != 10)
    {
        state++;
        preview_name[13] = '0' + state;
        cm_demo_printf("preview_name:%s\n",preview_name);
        int fd = cm_fs_open(preview_name, CM_FS_WBPLUS);
        if(fd < 0)
        {
            cm_demo_printf("cm_fs_open fail\n");
            return;
        }
        if(cm_fs_write(fd, pBuf, len) < 0)
        {
            cm_demo_printf("cm_fs_write fail\n");
        }
        cm_fs_close(fd);
    }
    else
    {
        cm_demo_printf("preview 10 end\n");
    }
}

static void cm_test_flushCamRecordBuffers_callback(void)
{
    cm_demo_printf("preview stop\n");
}

static uint8_t *qr_buff = NULL;

void cm_test_camera_operation(unsigned char *cmd[],int len)
{
    if(0 == strcmp("CAP",cmd[2]))
    {
        uint32_t width = 0;
        uint32_t height = 0;
        cm_camera_capture_cfg_t cfg = {0};
        cm_demo_printf("cm_test_camera_capture\n");
        cm_camera_sensor_set_data(&test_GC032a_spi);
        int32_t camera_open = cm_camera_open();
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,camera_open,cm_camera_open);
        if(camera_open < 0)
        {
            return;
        }
        
        int32_t camera_get_info = cm_camera_get_info(&width, &height);
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,camera_get_info,cm_camera_get_info);
        cm_demo_printf("cm_camera width %d height %d\n", width, height);

        cfg.recordFormat = atoi(cmd[3]);//set camera format 
        cfg.file_name = (uint8_t *)CAPTURE_FILE_NAME;
        int32_t camera_capture_take = cm_camera_capture_take(&cfg);
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,camera_capture_take,cm_camera_capture_take);
        
        int32_t camera_close = cm_camera_close();
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,camera_close,cm_camera_close);
    }
    else if(0 == strcmp("PREVIEW",cmd[2]))
    {
        uint32_t width = 0;
        uint32_t height = 0;
        cm_camera_preview_cfg_t cfg = {0};
        cm_demo_printf("cm_test_camera_preview\n");
        cm_camera_sensor_set_data(&test_GC032a_spi);
        int32_t camera_open = cm_camera_open();
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,camera_open,cm_camera_open);
        if(camera_open < 0)
        {
            return;
        }
        int32_t camera_get_info = cm_camera_get_info(&width, &height);
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,camera_get_info,cm_camera_get_info);
        cm_demo_printf("cm_camera width %d height %d\n", width, height);

        cfg.recordFormat = atoi(cmd[3]);//set camera format 
        cfg.enqueueCamRecordBuffer = cm_test_enqueueCamRecordBuffer_callback;
        cfg.flushCamRecordBuffers = cm_test_flushCamRecordBuffers_callback;
        int32_t camera_preview_start = cm_camera_preview_start(&cfg);
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,camera_preview_start,cm_camera_preview_start);
        osDelay(2000);
        int32_t camera_preview_stop = cm_camera_preview_stop();
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,camera_preview_stop,cm_camera_preview_stop);

        int32_t camera_close = cm_camera_close();
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,camera_close,cm_camera_close);
    }
    else if(0 == strcmp("QR",cmd[2]))
    {
        int datalen = 0;
        char data[2048] = {0};

        int32_t fd = cm_fs_open(CAPTURE_FILE_NAME, CM_FS_RB);
        
        if(fd < 0)
        {
            cm_demo_printf("[cm-qr] open %s failed\n", CAPTURE_FILE_NAME);
            return;
        }

        /* 从文件系统中读出图片，uyvy格式图片大小为 (width * height * 2) */
        qr_buff = cm_malloc(620000);
        if(qr_buff == NULL)
        {
            cm_demo_printf("[cm-qr] cm_malloc failed\n");
            return;
        }
        memset(qr_buff, 0, 620000);
        
        int ret = cm_fs_read(fd, qr_buff, 620000);
        cm_demo_printf("[cm-qr] read %d\n", ret);
        
        cm_fs_close(fd);

        /* 需在解码前调用cm_qr_convert_init，配置底层解码缓存区，缓存区将一直生效直到使用cm_qr_convert_destroy释放 */
        int qr_convert_init = cm_qr_convert_init(640, 480);
        OCTEST_FUNC_EXPECT_EQUAL_UINT32(0,qr_convert_init,cm_qr_convert_init);
        if(qr_convert_init < 0)
        {
            cm_demo_printf("[cm-qr] convert init failed\n");
        }

        /* 二维码解码，支持的图像格式见cm_qr_fmt_e枚举 */
        cm_qr_param_t qr_param = {
            .data   = qr_buff,
            .width  = 640,
            .height = 480,
            .format = CM_QR_FMT_UYVY,
        };
        int result = cm_qr_scan(&qr_param, data, &datalen);
        OCTEST_FUNC_EXPECT_EQUAL_UINT32(0,result,cm_qr_scan);
        if(result != CM_QR_RET_SUCCESS)
        {
            cm_demo_printf("[cm_qr] QR : failed code = (%d)\n", result);
        }
        else
        {
            cm_demo_printf("[cm_qr] QR : length = %d\n\"%s\"\n", datalen, data);
        }

        /* cm_qr_convert_destroy用于释放cm_qr_convert_init配置的缓存空间，请尽量减少使用次数 */
        cm_qr_convert_destroy();
        cm_free(qr_buff);
    }
    else
    {
        cm_demo_printf("param error!\n");
    }
}


